[BITS 32]

; kernel asm routines

global gdt_flush  ; flush a GDT
global idt_load   ; load an IDT
global tss_flush

;;
extern gdtp_phys
extern idtp_phys 

;; obsoleted by Napalm

extern gdtp          ; GDT pointer
extern idtp          ; IDT pointer
extern fault_handler ; default ISR handler
extern irq_handler   ; ditto, except for IRQs

; This will set up our new segment registers.

gdt_flush:
    lgdt [gdtp]         ; Load the GDT with our 'gp'
    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!
flush2:
    ret               ; Returns back


idt_load:
    lidt [idtp] ; load an idt
    ret

tss_flush:
   mov ax, 0x2b      ; Load the index of our TSS structure - The index is
                     ; 0x28, as it is the 5th selector and each is 8 bytes
                     ; long, but we set the bottom two bits (making 0x2B)
                     ; so that it has an RPL of 3, not zero.
   ltr ax        
   ret 

; ISR stubs

%macro isr_entry 2
global isr%1
isr%1:
	cli
	%if %2 == 0
	 push byte %2
	%endif
	push byte %1
	jmp isr_common_stub
%endmacro
		
isr_entry  0, 0 ; Divide By Zero Exception
isr_entry  1, 0 ; Debug Exception
isr_entry  2, 0 ; Non Maskable Interrupt Exception
isr_entry  3, 0 ; Breakpoint Exception (int 3)
isr_entry  4, 0 ; Into Detected Overflow Exception
isr_entry  5, 0 ; Out of Bounds Exception
isr_entry  6, 0 ; Invalid Opcode Exception
isr_entry  7, 0 ; Coprocessor Not Available Exception
isr_entry  8, 1 ; Double Fault Exception (code)
isr_entry  9, 0 ; Coprocessor Segment Overrun Exception
isr_entry 10, 1 ; Bad TSS Exception (code)
isr_entry 11, 1 ; Segment Not Present Exception (code)
isr_entry 12, 1 ; Stack Fault Exception (code)
isr_entry 13, 1 ; General Protection Fault Exception (code)
isr_entry 14, 1 ; Page Fault Exception (code)
isr_entry 15, 0 ; Unknown Interrupt Exception
isr_entry 16, 0 ; Coprocessor Fault / Floating Point Exception
isr_entry 17, 0 ; Alignment Check Exception (486+)
isr_entry 18, 0 ; Machine Check Exception (Pentium/586+)
isr_entry 19, 0 ; Reserved
isr_entry 20, 0 ; Reserved
isr_entry 21, 0 ; Reserved
isr_entry 22, 0 ; Reserved
isr_entry 23, 0 ; Reserved
isr_entry 24, 0 ; Reserved
isr_entry 25, 0 ; Reserved
isr_entry 26, 0 ; Reserved
isr_entry 27, 0 ; Reserved
isr_entry 28, 0 ; Reserved
isr_entry 29, 0 ; Reserved
isr_entry 30, 0 ; Reserved
isr_entry 31, 0 ; Reserved

; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
isr_common_stub:
    pusha
    push ds
    push es
    push fs
    push gs
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov eax, esp
    push eax
    mov eax, fault_handler
    call eax
    pop eax
    pop gs
    pop fs
    pop es
    pop ds
    popa
    add esp, 8
    iret



%macro irq_entry 2
global irq%1
irq%1:
	cli
	push byte 0
	push byte %2
	jmp irq_common_stub
%endmacro

extern sched_contextswitch

; irq_entry  0, 32 ; IRQ 0 - Special for scheduler
global irq0
irq0:
	cli
	pusha
	push ds
	push es
	push fs
	push gs
	mov eax, esp
	push eax

	; call the scheduler
	call sched_contextswitch
	mov esp, eax
	pop gs
	pop fs
	pop es
	pop ds
	popa
	; Call standard IRQ Handler
	push byte 0
	push byte 32
	jmp irq_common_stub
	
irq_entry  1, 33 ; IRQ 1
irq_entry  2, 34 ; IRQ 2
irq_entry  3, 35 ; IRQ 3
irq_entry  4, 36 ; IRQ 4
irq_entry  5, 37 ; IRQ 5
irq_entry  6, 38 ; IRQ 6
irq_entry  7, 39 ; IRQ 7
irq_entry  8, 40 ; IRQ 8
irq_entry  9, 41 ; IRQ 9
irq_entry 10, 42 ; IRQ 10
irq_entry 11, 43 ; IRQ 11
irq_entry 12, 44 ; IRQ 12
irq_entry 13, 45 ; IRQ 13
irq_entry 14, 46 ; IRQ 14
irq_entry 15, 47 ; IRQ 15


irq_common_stub:
    pusha
    push ds
    push es
    push fs
    push gs

    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov eax, esp

    push eax
    mov eax, irq_handler
    call eax
    pop eax

    pop gs
    pop fs
    pop es
    pop ds
    popa
    add esp, 8
    iret

